package com.zeng.config.restmodel;

import com.zeng.bean.restmodel.RestModelInfo;
import com.zeng.bean.restmodel.RestTableCreateParam;
import com.zeng.bean.restmodel.RestTableFieldInfo;
import com.zeng.bean.restmodel.RestTableInfo;
import com.zeng.mapper.restmodel.RestModelMapper;
import com.zeng.pojo.restmodel.BaseRestModel;
import com.zeng.service.restmodel.RestModelService;
import com.zeng.util.GenUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;

import java.util.ArrayList;
import java.util.List;

/**
 * 模型控制中心
 */
@Slf4j
@Data
@Component
public class RestModelCenter {

    WebApplicationContext appContext;

    private String basePackage = "com";

    private List<RestModelInfo> models = new ArrayList<>();

    public RestModelCenter(WebApplicationContext appContext) throws Exception { this.appContext = appContext; init();}

    public RestModelService getService(String modelName) {
        for (RestModelInfo model : models) {
            if(model.getModelName().equalsIgnoreCase(modelName)) {
                return RestModelService.load(model,appContext);
            }
        }
        return null;
    }



    public void init() throws InstantiationException, IllegalAccessException {
        //读取类
        List<Class<?>> allClasses = GenUtils.getAllClasses();

        for (Class<?> clazz : allClasses) {
            if(BaseRestModel.class.isAssignableFrom(clazz) && clazz != BaseRestModel.class) {
                log.info("load restModel > {}",clazz.getName());
                RestModelInfo mdInfo = RestModelInfo.load((Class<? extends BaseRestModel>) clazz);
                models.add(mdInfo);

                //处理建表
                handleTable(mdInfo);
            }
        }

        log.info("load restModel count {}",models.size());
    }

    /**
     * 处理表格信息
     */
    public void handleTable(RestModelInfo modelInfo) {
        RestModelMapper mapper = appContext.getBean(RestModelMapper.class);

        //不进行表操作
        if(modelInfo.getTbModel() == RestTBCreateMode.NONE) return;

        String tableName = modelInfo.getTableName();

        boolean b = mapper.existTable(tableName);

        //每次新建
        RestTableCreateParam restTableCreateParam = RestTableCreateParam.loadByTableClass(modelInfo.getClazz());
        if(modelInfo.getTbModel() == RestTBCreateMode.EVERY){
            if(b && modelInfo.onTableDrop(RestTableInfo.load(modelInfo))) mapper.dropTable(tableName);
            if(!modelInfo.onTableCreate(restTableCreateParam)) return;

            mapper.createTable(restTableCreateParam);
        }

        //不存在时新建
        if((modelInfo.getTbModel() == RestTBCreateMode.AUTO || modelInfo.getTbModel() == RestTBCreateMode.FORCE) && !b){
            if(!modelInfo.onTableCreate(restTableCreateParam)){
                return;
            };
            mapper.createTable(restTableCreateParam);
        }

        //差异时重建
        if(b && modelInfo.getTbModel() == RestTBCreateMode.FORCE) {
            List<RestTableFieldInfo> restTableFieldInfos = mapper.selectTableFields(tableName);
            RestTableInfo tbInfo = RestTableInfo.load(modelInfo);
            if(tbInfo.hasDifference(restTableFieldInfos)){

                log.info("rest 模型 {} 删除表",tableName);
                if(!modelInfo.onTableDrop(RestTableInfo.load(modelInfo))){
                    log.info("rest {} 模型{}表删除被生命周期方法阻止",modelInfo.getTbModel(),tableName);
                }else {
                    mapper.dropTable(tableName);
                }


                log.info("rest 模型 {} 创建表",tableName);
                if(!modelInfo.onTableCreate(restTableCreateParam)){
                    log.info("rest {} 模型{}表创建被生命周期方法阻止",modelInfo.getTbModel(),tableName);
                    return;
                };
                mapper.createTable(restTableCreateParam);
            }
        }
    }




}
